package com.mirror.utils.io;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.WeakReference;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.util.Log;

import com.mirror.llk.utils.Constant;
import com.mirror.utils.MemoryChecker;
import com.mirror.utils.base.BaseApplication;
import com.thoughtworks.xstream.core.util.Base64Encoder;

/**
 * @Title: 终端文件工具类
 * @Version: 1.0
 * @Author: QiYin
 * @Date: 2013-2-21
 * @Company: EmagSoftware
 */
public class FileUtils {

	/**
	 * TAG
	 */
	private static final String TAG = "FileUtil";

	/**
	 * 创建文件目录
	 * 
	 * @param dirPath
	 *            路径
	 * @return 文件目录
	 */
	public static File createDir(String dirPath) {
		Log.e(TAG, dirPath);
		File file = new File(dirPath);
		if (!file.exists()) {
			file.mkdirs();
		}
		Log.e(TAG, String.valueOf(file.exists()));
		return file;
	}

	public static void deleteDir(String dirPath) {
		File file = new File(dirPath);
		if (file.exists()) {
			clearDir(dirPath);
			file.delete();
		}
	}

	/**
	 * 读取终端文件
	 * 
	 * @param fileName
	 *            文件名
	 * @param moduleName
	 *            文件夹名
	 * @return 文件
	 */
	public static File readFile(String fileName, String moduleName, String photoLocation) {
		String terminalPath = getFilePath() + photoLocation + moduleName;
		Log.i(TAG, terminalPath);
		File file = new File(terminalPath, fileName);
		if (file.exists()) {
			return file;
		}
		return null;
	}

	/**
	 * 写文件至终端
	 * 
	 * @param dirPath
	 *            路径
	 * @param fileName
	 *            文件名
	 * @param moduleName
	 * @throws IOException
	 *             输入输出流异常
	 */
	public static void writeFile(String fileName, InputStream inputStream, String moduleName, String photoType) throws IOException {
		String terminalPath = getFilePath() + photoType + moduleName;
		// 创建文件目录
		createDir(terminalPath);
		File file = new File(terminalPath, fileName);
		// 写文件操作
		writeFile(new FileOutputStream(file), inputStream);
	}

	public static void writeFile(String filePath, String fileName, InputStream inputStream) throws FileNotFoundException {
		// 创建文件目录
		createDir(filePath);
		File file = new File(filePath, fileName);
		// 写文件操作
		writeFile(new FileOutputStream(file), inputStream);
	}

	/**
	 * 获取文件存储根目录
	 * 
	 * @return 文件存储根目录
	 */
	public static String getFilePath() {
		// SD卡存在
		if (MemoryChecker.externalMemoryAvailable()) {
			return Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + Constant.APP_NAME + File.separator;
		}
		// SD卡不存在
		else {
			return BaseApplication.getContext().getFilesDir().getAbsolutePath() + File.separator;
		}
	}

	/**
	 * 写文件操作
	 * 
	 * @param outputStream
	 *            输出流
	 * @param inputStream
	 *            输入流
	 */
	public static void writeFile(OutputStream outputStream, InputStream inputStream) {
		try {
			byte[] buffer = new byte[1 * 1024];
			int line = 0;
			while ((line = inputStream.read(buffer)) != -1) {
				outputStream.write(buffer, 0, line);
			}
			outputStream.flush();
		}
		catch (IOException e) {
			Log.e(TAG, "写入文件失败，发生输入输出流异常", e);
		}
		finally {
			try {
				outputStream.close();
				inputStream.close();
			}
			catch (IOException e) {
				Log.e(TAG, "关闭输入输出流异常", e);
			}
		}
	}

	/**
	 * 读输入流生成图片
	 * 
	 * @param inputStream
	 *            输入流
	 * @return 图片
	 * @throws IOException
	 *             输入输出流异常
	 */
	public static Drawable readDrawable(InputStream inputStream) throws IOException {
		return Drawable.createFromStream(inputStream, null);
	}

	/**
	 * 读取本地资源的图片
	 * 
	 * @param context
	 * @param resId
	 * @return
	 */
	public static Drawable readDrawable(Context context, int resId) {
		// 获取资源图片
		InputStream is = context.getResources().openRawResource(resId);
		try {
			return readDrawable(is);
		}
		catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 读输入流生成BASE64编码的图片字符串
	 * 
	 * @param inputStream
	 *            输入流
	 * @return BASE64编码的图片字符串
	 * @throws IOException
	 *             输入输出流异常
	 */
	public static String readEncryptFile(InputStream inputStream) throws IOException {
		byte[] buffer = new byte[inputStream.available()];
		inputStream.read(buffer);
		inputStream.close();
		// 对字节数组Base64编码
		return new Base64Encoder().encode(buffer);// 返回Base64编码过的字节数组字符串
	}

	/**
	 * 写BASE64编码的图片字符串为图片
	 * 
	 * @param imgStr
	 *            BASE64编码的图片字符串
	 * @return 是否成功
	 * @throws IOException
	 *             输入输出流异常
	 */
	// public static boolean writeEncryptFile(String fileName, String imgStr,
	// String moduleName, String photoLocation) throws IOException {
	// // 图像数据为空
	// if (imgStr == null) {
	// return false;
	// }
	// OutputStream outputStream = new FileOutputStream(new File(getFilePath() +
	// photoLocation + moduleName, fileName));
	// Base64Encoder decoder = new Base64Encoder();
	// // Base64解码
	// byte[] buffer = decoder.decode(imgStr);
	// for (int i = 0; i < buffer.length; ++i) {
	// // 调整异常数据
	// if (buffer[i] < 0) {
	// buffer[i] += 256;
	// }
	// }
	// outputStream.write(buffer);
	// outputStream.flush();
	// outputStream.close();
	// return true;
	//
	// }

	/**
	 * @param path
	 * @param w
	 * @param h
	 * @return
	 */
	public static Bitmap convertToBitmap(String path, int w, int h) {
		BitmapFactory.Options opts = new BitmapFactory.Options();
		// 设置为ture只获取图片大小
		opts.inJustDecodeBounds = true;
		opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
		// 返回为空
		BitmapFactory.decodeFile(path, opts);
		int width = opts.outWidth;
		int height = opts.outHeight;
		opts.inJustDecodeBounds = false;
		opts.inSampleSize = 1;
		WeakReference<Bitmap> weak = new WeakReference<Bitmap>(BitmapFactory.decodeFile(path, opts));
		Bitmap bitmap = Bitmap.createScaledBitmap(weak.get(), width, height, true);
		return FileUtils.convertToBitmap(bitmap, w, h);
	}

	/**
	 * 更改图片大小
	 * 
	 * @param bm
	 * @param newHeight
	 * @param newWidth
	 * @return
	 */
	public static Bitmap convertToBitmap(Bitmap bm, int newHeight, int newWidth) {
		int width = bm.getWidth();
		int height = bm.getHeight();
		float scaleWidth = ((float) newWidth) / width;
		float scaleHeight = ((float) newHeight) / height;
		// create a matrix for the manipulation
		Matrix matrix = new Matrix();
		// resize the bit map
		matrix.postScale(scaleWidth, scaleHeight);
		// recreate the new Bitmap
		Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
		return resizedBitmap;
	}

	/**
	 * 更改图片大小
	 * 
	 * @param bm
	 * @param newHeight
	 * @param newWidth
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static Drawable convertToDrawable(Drawable drawable, int newHeight, int newWidth) {
		Bitmap bm = drawable2Bitmap(drawable);
		int width = bm.getWidth();
		int height = bm.getHeight();
		float scaleWidth = ((float) newWidth) / width;
		float scaleHeight = ((float) newHeight) / height;
		// create a matrix for the manipulation
		Matrix matrix = new Matrix();
		// resize the bit map
		matrix.postScale(scaleWidth, scaleHeight);
		// recreate the new Bitmap
		Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
		return new BitmapDrawable(resizedBitmap);
	}

	/**
	 * Bitmap保存为文件
	 * 
	 * @param bitmap
	 * @param path
	 */
	public static void saveFile(Bitmap bitmap, String path) {
		FileOutputStream b = null;
		try {
			b = new FileOutputStream(path);
			bitmap.compress(Bitmap.CompressFormat.PNG, 100, b);// 把数据写入文件
		}
		catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		finally {
			try {
				b.flush();
				b.close();
			}
			catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * Bitmap保存为文件
	 * 
	 * @param bitmap
	 * @param file
	 */
	public static void saveFile(Bitmap bitmap, File file) {
		FileOutputStream b = null;
		try {
			b = new FileOutputStream(file);
			bitmap.compress(Bitmap.CompressFormat.JPEG, 100, b);// 把数据写入文件
		}
		catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		finally {
			try {
				b.flush();
				b.close();
			}
			catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public static File zipDir(String filePath, String filePrefix, String fileSuffix, String zipName) throws IOException {
		int BUFFER = 2048;
		ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(
		        new FileOutputStream(new File(filePath, zipName + Constant.FILE_TYPE_ZIP)), BUFFER));
		File[] dirFiles = new File(filePath).listFiles();
		for (File f : dirFiles) {
			if (f.isFile()) {
				if (filePrefix != null && !f.getName().startsWith(filePrefix)) {
					continue;
				}
				if (fileSuffix != null && !f.getName().endsWith(fileSuffix)) {
					continue;
				}
				ZipEntry entry = new ZipEntry(f.getName());
				out.putNextEntry(entry);
				BufferedInputStream buffer = new BufferedInputStream(new FileInputStream(f), BUFFER);
				byte data[] = new byte[BUFFER];
				int line;
				while ((line = buffer.read(data, 0, BUFFER)) != -1) {
					out.write(data, 0, line);
				}
				buffer.close();
			}
		}
		out.close();
		return new File(filePath + zipName + Constant.FILE_TYPE_ZIP);
	}

	/**
	 * 清空文件目录
	 * 
	 * @param moduleName
	 *            模块
	 * @throws IOException
	 *             输入输出流异常
	 */
	public static void clearDir(String fileType, String moduleName) {
		String path = FileUtils.getFilePath() + fileType + moduleName;
		File[] dirFiles = new File(path).listFiles();
		for (File f : dirFiles) {
			if (f.exists()) {
				f.delete();
			}
		}
	}

	public static void clearDir(String path) {
		File[] dirFiles = new File(path).listFiles();
		for (File f : dirFiles) {
			if (f.exists()) {
				f.delete();
			}
		}
	}

	public static File[] getDirFile(String fileType, String moduleName) {
		String path = FileUtils.getFilePath() + fileType + moduleName;
		return new File(path).listFiles();
	}

	/**
	 * 获取圆角图片
	 * 
	 * @param drawable
	 * @param pixels
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static Drawable toRoundCorner(Drawable drawable, int pixels) {
		BitmapDrawable bd = (BitmapDrawable) drawable;
		Bitmap bm = toRoundCorner(bd.getBitmap(), pixels);
		return new BitmapDrawable(bm);
	}

	/**
	 * 获取圆角图片
	 * 
	 * @param drawable
	 * @param pixels
	 * @return
	 */
	public static Bitmap toRoundCornerBitmap(Drawable drawable, int pixels) {
		return toRoundCorner(drawable2Bitmap(drawable), pixels);
	}

	/**
	 * drawable转成bitmap
	 * 
	 * @param drawable
	 * @return
	 */
	public static Bitmap drawable2Bitmap(Drawable drawable) {
		BitmapDrawable bd = (BitmapDrawable) drawable;
		return bd.getBitmap();
	}

	/**
	 * 获取圆角图片
	 * 
	 * @param bitmap
	 * @param pixels
	 * @return
	 */
	public static Bitmap toRoundCorner(Bitmap bitmap, int pixels) {
		Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
		Canvas canvas = new Canvas(output);
		final int color = 0xff424242;
		final Paint paint = new Paint();
		final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
		final RectF rectF = new RectF(rect);
		final float roundPx = pixels;
		paint.setAntiAlias(true);
		canvas.drawARGB(0, 0, 0, 0);
		paint.setColor(color);
		canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
		paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
		canvas.drawBitmap(bitmap, rect, rect, paint);
		return output;
	}

}
